---
title: "Party City Analysis Lease Locations by Rent Range"
subtitle: "Interactive Mapping and Summary of Auction Listings"
author: "Jim Amorin, CAE, MAI, SRA, AI-GRS, CDEI"
date: today
format:
  html:
    toc: true
    toc-depth: 3
    toc-location: left
    code-fold: true
    code-summary: "Show code"
    theme: cosmo
    embed-resources: true
    page-layout: full
    fig-width: 10
    fig-height: 7
execute:
  warning: false
  message: false
editor:
  markdown:
    wrap: 72
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(
  echo = TRUE,
  warning = FALSE,
  message = FALSE,
  fig.width = 10,
  fig.height = 7,
  dpi = 300
)

options(scipen = 999)
```

![](logo.png){width="260px"}

```{css, echo=FALSE}
.column-page {
  margin-bottom: 2em;
}

h1, h2, h3 {
  color: #000000;
}

.callout-note {
  border-left-color: #BF5700;
}

.key-finding {
  background-color: #f8f9fa;
  border-left: 4px solid #BF5700;
  padding: 1em;
  margin: 1em 0;
  border-radius: 4px;
  color: #000000;
}

.stat-box {
  background: linear-gradient(135deg, #BF5700 0%, #F2A900 100%);
  color: white;
  padding: 1.5em;
  border-radius: 8px;
  text-align: center;
  margin: 1em 0;
}

.stat-box h3 {
  color: white;
  margin-top: 0;
}

body {
  color: #000000;
}

p, li, td, th {
  color: #000000;
}
```

## Executive Summary

This report summarizes the auction listings in
`auction_listings.csv`, including an interactive map of lease locations
colored by rent range and several supporting charts for pricing context.

::: key-finding
**Key Focus:** Location patterns and rent range clustering across the
portfolio.
:::

## Company Overview
### Executive Summary

Party City Holdco Inc., once the largest specialty party supply retailer in the United States, ceased physical retail operations in early 2025 following its second Chapter 11 bankruptcy filing in less than two years. The wind-down of approximately 700 corporate-owned stores across 44 states represents one of the most significant single-retailer real estate disposition events in recent years, releasing millions of square feet of retail space back into the market.

This analysis provides context for understanding the scope of the Party City store portfolio, the factors that led to its liquidation, and the implications for local retail real estate markets where these locations existed. It is intended to accompany a mapped dataset of Party City store locations and to help frame the commercial real estate impact of this closure event.

### Company Background and Timeline

Steve Mandell founded Party City in 1986 as a single 4,000-square-foot store in East Hanover, New Jersey, specializing in party supplies. The concept found immediate traction, and the chain expanded rapidly through both corporate-owned locations and franchising. A pivotal early decision to dedicate substantial store space to Halloween merchandise proved transformative, eventually making the October holiday season responsible for as much as one-quarter of annual sales.

By the late 1990s, Party City had grown into a national chain during the era of so-called "category killers," when single-category megastores like Barnes & Noble, Toys R Us, and Circuit City dominated swaths of suburban retail. At its peak, the company operated over 800 stores and held a commanding market share in a multi-billion-dollar party supply industry. The company carried roughly 30,000 SKUs per location, offering everything from birthday supplies and seasonal decorations to costumes and helium balloons.

### The Private Equity Factor

Like many large specialty retailers of its era, Party City passed through private equity ownership. The resulting leveraged buyout (LBO) saddled the company with substantial debt. Interest payments alone consumed $102 million in 2022. This debt burden diverted capital away from two critical areas: store reinvestment and e-commerce development. While competitors were modernizing their operations and digital presence, Party City's physical stores grew increasingly dated and understaffed, and its online platform remained underdeveloped.

### The Path to Liquidation

**First Bankruptcy: January 2023**

Party City filed for Chapter 11 protection in January 2023, weighed down by approximately $1.7 billion in debt and the lingering effects of the COVID-19 pandemic on in-person celebrations. The company secured $150 million in debtor-in-possession financing and completed what it described as an expedited restructuring. By September 2023, the company emerged from bankruptcy, having eliminated roughly $1 billion in debt and closed over 60 underperforming locations.

However, the restructuring left approximately $800 million in remaining debt and did not include a compelling turnaround plan for the store fleet. The company exited bankruptcy with roughly 750 stores but lacked the financial capacity to make the kinds of technology and store-level investments that the post-pandemic retail environment demands.

**Second Bankruptcy and Wind-Down: December 2024**

Just 14 months after emerging from its first bankruptcy, Party City found itself unable to continue operating. In December 2024, CEO Barry Litwin informed employees that the company would commence an immediate wind-down. The company filed for Chapter 11 a second time in the Southern District of Texas, this time with no reorganization plan. Instead, it authorized going-out-of-business sales at approximately 700 remaining locations and engaged advisors to monetize its remaining assets, including its lease portfolio.

### Competitive and Market Factors

Party City's failure was not driven by a single cause but rather by the convergence of multiple structural and cyclical headwinds.

- Debt burden: The private equity legacy left the company financially fragile, with interest payments consuming resources that should have funded modernization.
- Pandemic impact: COVID-19 devastated the in-person celebration market, Party City's core business. Even after restrictions eased, consumer habits around entertaining shifted significantly.
- Inflationary pressure: Rising costs squeezed margins while simultaneously tightening consumer party budgets, creating pressure from both the cost and revenue sides.
- Competitive erosion: Spirit Halloween expanded aggressively beyond its seasonal pop-up model. Amazon, Walmart, and even Home Depot (with its viral giant skeleton decorations) captured party supply market share. These competitors offered either greater convenience or more compelling seasonal experiences.
- Helium shortage: A global helium shortage disrupted the company's balloon business, which had been a meaningful revenue stream and an in-store traffic driver.
- Underinvestment: Years of deferred store maintenance and technology investment left Party City with aging, unappealing locations and a weak digital presence at a time when omnichannel capability had become table stakes.

### The Real Estate Portfolio

**Portfolio Characteristics**

The Party City store fleet, at the time of the December 2024 bankruptcy filing, consisted of approximately 700 corporate-owned locations across 44 states. The portfolio was diverse in terms of both format and geography. Key characteristics include the following.

The 10,000-to-12,000-square-foot junior anchor format is particularly noteworthy from a real estate perspective. This size category sits in a supply-constrained segment of the market. According to CoStar analytics, very little new construction of mid-sized retail boxes has occurred over the past 15 years, making existing spaces in this format a scarce commodity in many trade areas.

**Lease Disposition Process**

A&G Real Estate Partners was retained as the real estate advisor for the lease disposition process. The firm put 695 store leases up for auction in early February 2025, with the physical auction held at the Manhattan offices of Paul, Weiss, Rifkind, Wharton & Garrison LLP. The process ultimately generated approximately $14.5 million in gross proceeds from lease designation rights, with the potential for additional value from remaining unsold leases.

**Key Auction Results**

Of the roughly 700 leases offered, bids were received for approximately 250 locations. This means that over 400 former Party City sites did not attract competitive bids at auction. While the national retail vacancy rate stood at approximately 4.1% at the time, the auction results demonstrate that not every available location is equally desirable, even in a tight market for retail space.

**Post-Closure Tenant Demand**

Despite the large number of unbid locations, the types of spaces vacated by Party City are broadly attractive to several expanding tenant categories. A&G identified the following as strong candidates for backfill: discount and value retailers (Dollar Tree, Five Below), gyms and fitness concepts, entertainment tenants, local specialty retailers, furniture stores, and medical office/clinic operators.

The junior anchor format vacated by Party City represents turnkey space in established shopping centers, often with favorable lease terms available through the bankruptcy process. For expanding operators, these locations offer immediate occupancy without the long lead times associated with new construction. Industry analysts at CoStar have noted that this is precisely the type of retail format that is no longer being built but for which meaningful tenant demand still exists.

### Brand Disposition and Afterlife

While the physical stores closed, the Party City brand itself survived. Ad Populum, LLC, a Santa Monica-based marketer of pop culture goods and costumes, acquired substantially all of Party City's intellectual property and the related Amscan wholesale operating assets through a winning auction bid valued at $20 million ($16 million in cash plus additional consideration). This represented twice the stalking horse bid value. Ad Populum's brand portfolio includes Chia Pet, Rubies costumes, and Graceland-branded merchandise.

As of mid-2025, the PartyCity.com website was relaunched as an operational e-commerce platform under new ownership. In a notable development, Staples announced in late 2025 that it would launch a Party City store-within-a-store concept in its retail locations, signaling that the brand retains meaningful consumer recognition even after the physical chain's closure.

### Broader Retail Real Estate Context

Party City's closure is not an isolated event. It sits within a wave of retail bankruptcies and store closings that accelerated through 2024 and 2025. According to Coresight Research, approximately 7,300 stores closed in 2024 (up 57% from 2023), and over 8,100 stores closed in 2025. Fifty retail bankruptcies occurred in 2024 alone, roughly double the prior year's total. An estimated 15,000 store closures were projected for 2025.

Other significant closures in this period include Joann (all ~800 stores), Big Lots, Forever 21, Rite Aid, and substantial reductions by Macy's and Kohl's. Many of these chains share common characteristics with Party City: legacy debt from private equity ownership, deferred investment in stores and technology, and an inability to adapt to post-pandemic consumer behavior. The closures collectively released millions of square feet of retail space into local markets, creating both challenges for landlords and opportunities for expanding tenants.

### Implications for Appraisal and Valuation

For commercial real estate appraisers, the Party City wind-down offers several important analytical considerations.

- Market rent analysis: Properties formerly occupied by Party City may require careful analysis of achievable rents, particularly if the location did not attract bids at auction. The distinction between locations that were quickly re-tenanted and those that remain vacant provides insight into locational quality and trade area strength.
- Absorption and vacancy: The simultaneous release of 700 locations into the market creates a natural experiment in retail absorption. Appraisers working in markets with former Party City locations should track re-tenanting velocity as a barometer of local retail demand.
- Highest and best use: The size range of 7,000 to 46,000 square feet means that some former Party City spaces may be candidates for subdivision, conversion to non-retail uses (medical, fitness, entertainment), or redevelopment entirely.
- Lease comparables: The bankruptcy auction process provides a dataset of market-tested lease values that can inform comparable rent analysis. The $14.5 million in gross lease proceeds across the portfolio offers a macro-level benchmark, while individual lease assignments provide transaction-level data.

### Conclusion

The Party City closure represents the end of a 39-year retail institution but also a significant real estate disposition event with measurable impacts on local markets. The mapped store data that accompanies this analysis provides a geographic view of the affected locations. When viewed alongside local market conditions, tenant demand, and absorption trends, this data can inform both investment and valuation decisions in the affected trade areas.

The Party City story also serves as a cautionary case study in the risks of excessive leverage, deferred investment, and the accelerating pace of competitive disruption in specialty retail. For practitioners in the real estate and appraisal profession, it underscores the importance of monitoring retail tenant credit quality, understanding the structural shifts in consumer behavior, and building analytical frameworks that account for the increasing velocity of retail market change.
```{r load-packages}
options(repos = c(CRAN = "https://cloud.r-project.org/"))

required_packages <- c(
  "tidyverse", "lubridate", "sf", "leaflet", "maps",
  "scales", "knitr", "plotly", "DT"
)

new_packages <- required_packages[!(required_packages %in% installed.packages()[, "Package"])]
if (length(new_packages)) install.packages(new_packages, quiet = TRUE)

library(tidyverse)
library(lubridate)
library(sf)
library(leaflet)
library(maps)
library(scales)
library(knitr)
library(plotly)
library(DT)

chart_colors <- c(
  "Series1" = "#BF5700",
  "Series2" = "#333F48",
  "Series3" = "#61A5C2",
  "Series4" = "#A7A8AA",
  "Series5" = "#F2A900"
)

theme_set(theme_minimal(base_size = 12) +
  theme(
    plot.title = element_text(color = chart_colors["Series1"], face = "bold", size = 16),
    plot.subtitle = element_text(color = chart_colors["Series2"], size = 12),
    axis.title = element_text(color = chart_colors["Series2"]),
    legend.position = "bottom"
  ))
```
## Data Preparation

This section standardizes column names, cleans rent and size fields, parses
lease expiration dates, and creates rent-range buckets used throughout the
visuals.

```{r load-data}
auction_data <- read_csv("auction_listings.csv", show_col_types = FALSE)

col_map <- list(
  Sq_Ft = c("Sq. Ft.", "Sq Ft", "SqFt", "Sq_Ft"),
  Rent = c("Base Rent PSF", "Rent", "Base_Rent_PSF"),
  LED = c("LED", "Lease Expiration Date"),
  Options = c("Options", "Renewal Options"),
  lat = c("lat", "latitude", "Lat", "Latitude"),
  lon = c("lon", "longitude", "Lon", "Longitude")
)

rename_map <- lapply(col_map, function(cands) cands[cands %in% names(auction_data)][1])
missing_cols <- names(rename_map)[sapply(rename_map, function(x) is.na(x) || length(x) == 0)]
if (length(missing_cols)) {
  stop("Missing required columns: ", paste(missing_cols, collapse = ", "))
}

rename_args <- setNames(unlist(rename_map), names(rename_map))
auction_data <- dplyr::rename(auction_data, !!!rename_args)

auction_data <- auction_data %>%
  mutate(
    Rent = str_replace_all(Rent, "[^0-9.]", ""),
    Sq_Ft = as.numeric(Sq_Ft),
    Rent = as.numeric(Rent),
    LED = mdy(LED),
    Total_Renewal_Years = as.numeric(str_extract(Options, "\\d+")) *
      as.numeric(str_extract(Options, "(?<=@ )\\d+"))
  ) %>%
  mutate(
    Rent_Range = case_when(
      Rent < 10 ~ "Below $10",
      Rent >= 10 & Rent < 15 ~ "$10 - $15",
      Rent >= 15 & Rent < 20 ~ "$15 - $20",
      Rent >= 20 ~ "Above $20",
      TRUE ~ "Unknown"
    )
  )
```

```{r data-summary}
summary_stats <- auction_data %>%
  summarise(
    `Total Listings` = as.character(n()),
    `Mean Rent (PSF)` = dollar(mean(Rent, na.rm = TRUE)),
    `Median Rent (PSF)` = dollar(median(Rent, na.rm = TRUE)),
    `Mean Size (Sq Ft)` = comma(round(mean(Sq_Ft, na.rm = TRUE))),
    `Median Size (Sq Ft)` = comma(round(median(Sq_Ft, na.rm = TRUE)))
  ) %>%
  pivot_longer(everything(), names_to = "Metric", values_to = "Value")

kable(summary_stats, align = c("l", "r"), caption = "Dataset Summary")
```

## Interactive Map

The map below shows each lease location and lets you explore patterns by rent
range. Marker clustering is enabled to keep dense areas readable.

```{r map-data}
auction_sf <- st_as_sf(auction_data, coords = c("lon", "lat"), crs = 4326, remove = FALSE)

popup_cols <- c("Property", "Property_Name", "Address", "City", "State", "Zip",
                "Rent", "Sq_Ft", "LED", "Options", "Rent_Range")
popup_cols <- popup_cols[popup_cols %in% names(auction_sf)]

popup_html <- apply(auction_sf[popup_cols], 1, function(row) {
  items <- paste0("<b>", names(row), ":</b> ", row, collapse = "<br>")
  items
})

pal <- colorFactor(
  palette = c(chart_colors["Series3"], chart_colors["Series5"], chart_colors["Series1"], "#6B7280"),
  levels = c("Below $10", "$10 - $15", "$15 - $20", "Above $20", "Unknown")
)
```

```{r leaflet-map, fig.height=8}
leaflet(auction_sf) %>%
  addProviderTiles(providers$CartoDB.Positron) %>%
  addCircleMarkers(
    radius = 5,
    color = ~pal(Rent_Range),
    fillColor = ~pal(Rent_Range),
    fillOpacity = 0.7,
    weight = 1,
    popup = popup_html,
    clusterOptions = markerClusterOptions()
  ) %>%
  addLegend(
    position = "bottomright",
    colors = pal(c("Below $10", "$10 - $15", "$15 - $20", "Above $20", "Unknown")),
    labels = c("Below $10", "$10 - $15", "$15 - $20", "Above $20", "Unknown"),
    title = "Rent Range",
    opacity = 0.8
  )
```


## Pricing and Size Distribution

```{r rent-range-chart, fig.height=6}
rent_range_plot <- auction_data %>%
  count(Rent_Range) %>%
  mutate(Rent_Range = fct_relevel(Rent_Range, "Below $10", "$10 - $15", "$15 - $20", "Above $20", "Unknown")) %>%
  ggplot(aes(x = Rent_Range, y = n, fill = Rent_Range)) +
  geom_col(color = "white", linewidth = 0.4) +
  scale_fill_manual(values = c(
    "Below $10" = chart_colors["Series3"],
    "$10 - $15" = chart_colors["Series5"],
    "$15 - $20" = chart_colors["Series1"],
    "Above $20" = chart_colors["Series2"],
    "Unknown" = chart_colors["Series4"]
  )) +
  labs(
    title = "Listings by Rent Range",
    x = NULL,
    y = "Number of Listings",
    fill = NULL
  )

ggplotly(rent_range_plot)
```

```{r rent-vs-size, fig.height=6}
rent_size_plot <- auction_data %>%
  filter(!is.na(Rent), !is.na(Sq_Ft)) %>%
  ggplot(aes(x = Sq_Ft, y = Rent)) +
  geom_point(alpha = 0.6, size = 2, color = "#BF5700") +
  geom_smooth(method = "loess", se = FALSE, color = chart_colors["Series2"]) +
  scale_x_continuous(labels = comma) +
  labs(
    title = "Rent vs. Size",
    subtitle = "Each point is a listing; line shows overall trend",
    x = "Square Feet",
    y = "Base Rent (PSF)"
  )

ggplotly(rent_size_plot)
```

## State Distribution

```{r rent-range-by-state, fig.height=7}
state_summary <- auction_data %>%
  filter(!is.na(State)) %>%
  count(State, Rent_Range) %>%
  group_by(State) %>%
  mutate(Total = sum(n)) %>%
  ungroup() %>%
  arrange(desc(Total))

top_states <- state_summary %>%
  distinct(State, Total) %>%
  slice_max(Total, n = 15, with_ties = FALSE) %>%
  pull(State)

state_plot_data <- state_summary %>%
  filter(State %in% top_states) %>%
  mutate(State = fct_reorder(State, Total))

state_plot_data <- state_plot_data %>%
  mutate(
    Rent_Range = factor(Rent_Range, levels = c("Below $10", "$10 - $15", "$15 - $20", "Above $20", "Unknown")),
    State = factor(State, levels = unique(State))
  )

state_colors <- c(
  "Below $10" = "#61A5C2",
  "$10 - $15" = "#1F3A5F",
  "$15 - $20" = "#BF5700",
  "Above $20" = "#333F48",
  "Unknown" = "#A7A8AA"
)

state_plot <- plot_ly(type = "bar", orientation = "h")
for (range in levels(state_plot_data$Rent_Range)) {
  data_slice <- state_plot_data %>% filter(Rent_Range == range)
  if (nrow(data_slice) == 0) {
    next
  }
  state_plot <- state_plot %>%
    add_trace(
      data = data_slice,
      x = ~n,
      y = ~State,
      name = range,
      marker = list(color = as.character(unname(state_colors[range])))
    )
}

state_plot %>%
  layout(
    barmode = "stack",
    title = "Top States by Listings (Rent Range Split)",
    xaxis = list(title = "Number of Listings"),
    yaxis = list(title = "")
  )
```

## City Distribution

```{r rent-range-by-city, fig.height=7}
city_summary <- auction_data %>%
  filter(!is.na(City), !is.na(State)) %>%
  mutate(City_State = paste0(City, ", ", State)) %>%
  count(City_State, Rent_Range) %>%
  group_by(City_State) %>%
  mutate(Total = sum(n)) %>%
  ungroup() %>%
  arrange(desc(Total))

top_cities <- city_summary %>%
  distinct(City_State, Total) %>%
  slice_max(Total, n = 15, with_ties = FALSE) %>%
  pull(City_State)

city_plot_data <- city_summary %>%
  filter(City_State %in% top_cities) %>%
  mutate(City_State = fct_reorder(City_State, Total))

city_plot_data <- city_plot_data %>%
  mutate(
    Rent_Range = factor(Rent_Range, levels = c("Below $10", "$10 - $15", "$15 - $20", "Above $20", "Unknown")),
    City_State = factor(City_State, levels = unique(City_State))
  )

city_colors <- c(
  "Below $10" = "#61A5C2",
  "$10 - $15" = "#1F3A5F",
  "$15 - $20" = "#BF5700",
  "Above $20" = "#333F48",
  "Unknown" = "#A7A8AA"
)

city_plot <- plot_ly(type = "bar", orientation = "h")
for (range in levels(city_plot_data$Rent_Range)) {
  data_slice <- city_plot_data %>% filter(Rent_Range == range)
  if (nrow(data_slice) == 0) {
    next
  }
  city_plot <- city_plot %>%
    add_trace(
      data = data_slice,
      x = ~n,
      y = ~City_State,
      name = range,
      marker = list(color = as.character(unname(city_colors[range])))
    )
}

city_plot %>%
  layout(
    barmode = "stack",
    title = "Top Cities by Listings (Rent Range Split)",
    xaxis = list(title = "Number of Listings"),
    yaxis = list(title = "")
  )
```

## Lease Expiration Timeline

```{r led-timeline, fig.height=6}
led_timeline <- auction_data %>%
  filter(!is.na(LED)) %>%
  mutate(LED_Quarter = floor_date(LED, "quarter")) %>%
  count(LED_Quarter) %>%
  arrange(LED_Quarter) %>%
  mutate(LED_Label = paste0(year(LED_Quarter), " Q", quarter(LED_Quarter)),
         LED_Label = factor(LED_Label, levels = LED_Label))

led_plot <- ggplot(led_timeline, aes(x = LED_Label, y = n, group = 1)) +
  geom_line(color = chart_colors["Series1"], linewidth = 1.2) +
  geom_point(color = chart_colors["Series1"], size = 2) +
  labs(
    title = "Lease Expiration Dates by Quarter",
    x = "Lease Expiration Quarter",
    y = "Number of Listings"
  ) +
  theme(
    axis.text.x = element_text(angle = 45, hjust = 1)
  )

ggplotly(led_plot)
```

## Interactive Listings Table

```{r listings-table}
table_cols <- c("Store #", "Store Name", "Address", "City", "State", "Rent", "Sq_Ft", "LED", "Rent_Range")
table_data <- auction_data %>%
  select(any_of(table_cols))

datatable(
  table_data,
  filter = "top",
  rownames = FALSE,
  options = list(pageLength = 15, scrollX = TRUE)
)
```

## Company Context (Public Sources)

::: callout-note
The following notes summarize public reporting on Party City. Use these as
context only and verify with primary sources before making decisions.

- Wikipedia provides a concise history and timeline of restructurings, store
  closures, and ownership changes.
  https://en.wikipedia.org/wiki/Party_City
- CNN reported the wind-down announcement and store-closure timing targeting
  Feb. 28, 2025.
  https://www.cnn.com/2024/12/20/business/party-city-shut-down/index.html
- Retail Dive reported the 2024 bankruptcy, store liquidation plans, and store
  footprint at the filing.
  https://www.retaildive.com/news/party-city-chapter-11-bankruptcy-close-stores-liquidation/736219/
- Retail Dive reported the IP sale and lease auction outcomes (top bidders and
  proceeds).
  https://www.retaildive.com/news/party-city-intellectual-property-store-leases-amscan-wholesale-acquired-bankruptcy-auction/739651/
- CBS News reported the December 2024 bankruptcy filing and corporate layoffs.
  https://www.cbsnews.com/news/party-city-files-for-bankruptcy/
:::

::: stat-box
### Portfolio Snapshot

**Listings:** `r nrow(auction_data)`

**Median Rent (PSF):** `r dollar(median(auction_data$Rent, na.rm = TRUE))`

**Median Size (Sq Ft):** `r comma(round(median(auction_data$Sq_Ft, na.rm = TRUE)))`
:::
